﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using EDXLHistory;
using EDXLSharp.EDXLDELib;
using ICNETDAL;
using ICNETServices;
using Microsoft.ServiceModel.Web;

namespace ICNETREST
{
  [ServiceContract(Namespace = "urn:icnet:mitre:org:RSSService")]
  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
  public class RSSService
  {
    [WebGet(UriTemplate = "RSS/All"), OperationContract]
    public Atom10FeedFormatter GetRSS()
    {
      try
      {
        SyndicationFeed feed = new SyndicationFeed();
        XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
        String icnetNs = ICNETSOAConstants.ICNETNamespace;
        feed.AttributeExtensions.Add(n, icnetNs);

        List<SyndicationItem> items = null;
        items = RSSDal.GetAllRSSItems();
        feed.Title = new TextSyndicationContent("IC.NET All RSS Items: ");
        feed.Items = items == null ? new List<SyndicationItem>() : items;
        //feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
        feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
        WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
        return feed.GetAtom10Formatter();
      }
      catch(Exception Ex)
      {
        SyndicationFeed feed = new SyndicationFeed();
        XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
        String icnetNs = ICNETSOAConstants.ICNETNamespace;
        feed.AttributeExtensions.Add(n, icnetNs);

        feed.Title = new TextSyndicationContent("Error: " + Ex.ToString());
        feed.Items = new List<SyndicationItem>();
        feed.LastUpdatedTime = DateTimeOffset.Now;
        feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
        WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
        return feed.GetAtom10Formatter();
      }
    }

    [WebInvoke(UriTemplate = "RSS/PostRSS", Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    public XElement PostRSS(XElement xe)
    {
      try
      {
        RSSDal.SaveRSSItem(xe);
        XElement xeSuccess = new XElement("Result");
        xeSuccess.Value = "Success";
        return xeSuccess;
      }
      catch (Exception Ex)
      {
        XElement xeError = new XElement("Error");
        xe.Value = Ex.ToString();
        return xeError;
      }
    }

    [WebInvoke(UriTemplate = "RSS/PostStatus", Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    public XElement PostStatus(XElement xe)
    {
      try
      {
        RSSDal.SaveStatus(xe);
        XElement xeSuccess = new XElement("Result");
        xeSuccess.Value = "Success";
        return xeSuccess;
      }
      catch (Exception Ex)
      {
        XElement xeError = new XElement("Error");
        xe.Value = Ex.ToString();
        return xeError;
      }
    }

    [WebInvoke(UriTemplate = "RSS/PostEDXLDE", Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    public XElement PostDE(XElement xe)
    {
      EDXLDE de = new EDXLDE(xe.ToString(SaveOptions.None));

      if (de != null)
      {
        History.AddServiceStatusToDB(de.DistributionID, de.SenderID, de.DateTimeSent.ToLocalTime(),
              "RSSService", History.ServiceStatusEnum.Started, DateTime.Now, "Starting Work");
      }

      try
      {
        RSSDal.SaveDE(xe);

        if (de != null)
        {
          History.AddServiceStatusToDB(de.DistributionID, de.SenderID, de.DateTimeSent.ToLocalTime(),
              "RSSService", History.ServiceStatusEnum.Success, DateTime.Now, "Added DE to DB");
        }

        //XElement xeSuccess = new XElement("Result");
        //xeSuccess.Value = "Success";
        return xe;
      }
      catch (Exception Ex)
      {
        if (de != null)
        {
          History.AddServiceStatusToDB(de.DistributionID, de.SenderID, de.DateTimeSent.ToLocalTime(),
            "RSSService", History.ServiceStatusEnum.Error, DateTime.Now, Ex.ToString());
        }

        XElement xeError = new XElement("Error");
        xe.Value = Ex.ToString();
        return xeError;
      }
    }

    /// <summary>
    /// Iterates thorugh a list of syndication items to find the date of the most recent one. 
    /// </summary>
    /// <param name="items">The list to be iterated through. </param>
    /// <returns>The date and time of the most recent item.</returns>
    private DateTimeOffset GetMostRecentSyndicationItemTime(List<SyndicationItem> items)
    {
      if (items == null || items.Count == 0)
      {
        return DateTimeOffset.Now;
      }

      DateTimeOffset mostRecentTime = items[0].LastUpdatedTime;
      foreach (SyndicationItem item in items)
      {
        if (item.LastUpdatedTime.CompareTo(mostRecentTime) < 0)
        {
          mostRecentTime = item.LastUpdatedTime;
        }
      }

      return mostRecentTime;
    }
  }
}
